package checker

import (
	"context"
	"sync"
	"time"
	"vdrift/internal/logger"
)

type Pool struct {
	checkers []Checker
	interval time.Duration
	results  map[string]Result
	mu       sync.RWMutex
}

func NewPool(checkers []Checker) *Pool {
	return &Pool{
		checkers: checkers,
		results:  make(map[string]Result),
	}
}

func (p *Pool) Start(ctx context.Context) {
	// 启动时立即执行一次
	p.runOnce(ctx)

	ticker := time.NewTicker(2 * time.Second) // 统一调度频率
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			logger.WithComponent("checker").Info("checker pool stopped")
			return
		case <-ticker.C:
			p.runOnce(ctx)
		}
	}
}

func (p *Pool) runOnce(ctx context.Context) {
	var wg sync.WaitGroup
	tempResults := make(map[string]Result)

	for _, c := range p.checkers {
		wg.Add(1)
		go func(ch Checker) {
			defer wg.Done()
			result := ch.Check(ctx)
			tempResults[ch.Name()] = result
			logger.WithHealthCheck(result.Name, result.OK, result.Detail).Info("health check result")
		}(c)
	}

	wg.Wait()

	p.mu.Lock()
	p.results = tempResults
	p.mu.Unlock()
}

func (p *Pool) GetResults() map[string]Result {
	p.mu.RLock()
	defer p.mu.RUnlock()
	copied := make(map[string]Result)
	for k, v := range p.results {
		copied[k] = v
	}
	return copied
}

func (p *Pool) IsHealthy() bool {
	p.mu.RLock()
	defer p.mu.RUnlock()
	for _, r := range p.results {
		if !r.OK {
			return false
		}
	}
	return len(p.results) == len(p.checkers) && len(p.checkers) > 0
}

func (p *Pool) GetFailedCount() int {
	p.mu.RLock()
	defer p.mu.RUnlock()
	count := 0
	for _, r := range p.results {
		if !r.OK {
			count++
		}
	}
	return count
}
